package com.zjcloud.jwgl.service.impl;

import java.util.List;
import java.util.ArrayList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.transaction.annotation.Transactional;
import com.zjcloud.jwgl.mapper.AcScheduleConstraintMapper;
import com.zjcloud.jwgl.mapper.AcScheduleConstraintTemplateMapper;
import com.zjcloud.jwgl.domain.AcScheduleConstraint;
import com.zjcloud.jwgl.domain.AcScheduleConstraintTemplate;
import com.zjcloud.jwgl.service.IAcScheduleConstraintService;
import com.zjcloud.common.utils.DateUtils;
import com.zjcloud.common.utils.SecurityUtils;

/**
 * 排课约束条件Service业务层处理
 * 
 * @author wxl
 * @date 2024-09-13
 */
@Service
public class AcScheduleConstraintServiceImpl implements IAcScheduleConstraintService 
{
    @Autowired
    private AcScheduleConstraintMapper acScheduleConstraintMapper;
    
    @Autowired
    private AcScheduleConstraintTemplateMapper acScheduleConstraintTemplateMapper;
    
    // @Autowired
    // 由于使用了@Cacheable和@CacheEvict注解,RedisTemplate已不再直接使用
    // private RedisTemplate<String, Object> redisTemplate;

    /**
     * 查询排课约束条件
     * 
     * @param id 排课约束条件主键
     * @return 排课约束条件
     */
    @Override
    @Cacheable(value = "schedule_constraint", key = "'constraint:' + #id")
    public AcScheduleConstraint selectAcScheduleConstraintById(Long id)
    {
        return acScheduleConstraintMapper.selectAcScheduleConstraintById(id);
    }

    /**
     * 查询排课约束条件列表
     * 
     * @param acScheduleConstraint 排课约束条件
     * @return 排课约束条件
     */
    @Override
    public List<AcScheduleConstraint> selectAcScheduleConstraintList(AcScheduleConstraint acScheduleConstraint)
    {
        return acScheduleConstraintMapper.selectAcScheduleConstraintList(acScheduleConstraint);
    }

    /**
     * 新增排课约束条件
     * 
     * @param acScheduleConstraint 排课约束条件
     * @return 结果
     */
    @Override
    @CacheEvict(value = "schedule_constraint", allEntries = true)
    public int insertAcScheduleConstraint(AcScheduleConstraint acScheduleConstraint)
    {
        acScheduleConstraint.setCreateTime(DateUtils.getNowDate());
        return acScheduleConstraintMapper.insertAcScheduleConstraint(acScheduleConstraint);
    }

    /**
     * 修改排课约束条件
     * 
     * @param acScheduleConstraint 排课约束条件
     * @return 结果
     */
    @Override
    @CacheEvict(value = "schedule_constraint", key = "'constraint:' + #acScheduleConstraint.id")
    public int updateAcScheduleConstraint(AcScheduleConstraint acScheduleConstraint)
    {
        acScheduleConstraint.setUpdateTime(DateUtils.getNowDate());
        return acScheduleConstraintMapper.updateAcScheduleConstraint(acScheduleConstraint);
    }

    /**
     * 批量删除排课约束条件
     * 
     * @param ids 需要删除的排课约束条件主键
     * @return 结果
     */
    @Override
    @CacheEvict(value = "schedule_constraint", allEntries = true)
    public int deleteAcScheduleConstraintByIds(Long[] ids)
    {
        return acScheduleConstraintMapper.deleteAcScheduleConstraintByIds(ids);
    }

    /**
     * 删除排课约束条件信息
     * 
     * @param id 排课约束条件主键
     * @return 结果
     */
    @Override
    @CacheEvict(value = "schedule_constraint", key = "'constraint:' + #id")
    public int deleteAcScheduleConstraintById(Long id)
    {
        return acScheduleConstraintMapper.deleteAcScheduleConstraintById(id);
    }

    /**
     * 批量更新约束权重
     * 
     * @param constraints 约束条件列表
     * @return 更新成功的记录数
     */
    @Override
    @CacheEvict(value = "schedule_constraint", allEntries = true)
    public int updateConstraintWeights(List<AcScheduleConstraint> constraints)
    {
        if (constraints == null || constraints.isEmpty()) {
            return 0;
        }

        int successCount = 0;
        for (AcScheduleConstraint constraint : constraints) {
            // 设置更新时间
            constraint.setUpdateTime(DateUtils.getNowDate());
            // 只更新权重相关字段
            int result = acScheduleConstraintMapper.updateConstraintWeight(constraint.getId(), constraint.getWeight());
            if (result > 0) {
                successCount++;
            }
        }
        return successCount;
    }
    
    /**
     * 获取指定学期的所有启用约束条件
     * 
     * @param semester 学期
     * @return 约束条件列表
     */
    @Override
    @Cacheable(value = "schedule_constraint", key = "'semester:' + #semester")
    public List<AcScheduleConstraint> getEnabledConstraints(String semester)
    {
        AcScheduleConstraint query = new AcScheduleConstraint();
        query.setSemester(semester);
        query.setEnabled("1"); // 1表示启用
        return acScheduleConstraintMapper.selectAcScheduleConstraintList(query);
    }
    
    /**
     * 批量更新约束条件权重
     * 
     * @param constraints 约束条件列表
     * @return 结果
     */
    /**
     * 批量更新约束权重
     * 
     * @param constraints 约束条件列表
     * @return 更新成功的记录数
     */
    /**
     * 从模板初始化约束条件数据
     *
     * @param templateName 模板名称
     * @param semester 学期
     * @return 初始化结果
     */
    @Override
    @Transactional
    @CacheEvict(value = "acScheduleConstraint", allEntries = true)
    public int initConstraintsFromTemplate(String templateName, String semester) {
        // 查询模板数据列表
        List<AcScheduleConstraintTemplate> templates = acScheduleConstraintTemplateMapper.selectByTemplateName(templateName);
        if (templates == null || templates.isEmpty()) {
            return 0;
        }

        // 删除该学期的现有约束条件
        acScheduleConstraintMapper.deleteConstraintsBySemester(semester);

        // 根据模板创建新的约束条件
        List<AcScheduleConstraint> constraints = new ArrayList<>();
        String currentUser = SecurityUtils.getUsername();
        
        // 处理所有模板
        for (AcScheduleConstraintTemplate template : templates) {
            AcScheduleConstraint constraint = new AcScheduleConstraint();
            constraint.setName(template.getConstraintName());
            // 需要根据约束类型名称查找对应的约束类型ID
            // 这里暂时设置为1，实际应该根据template.getConstraintType()查找对应的ID
            constraint.setConstraintTypeId(1L);
            constraint.setWeight(template.getDefaultWeight());
            constraint.setEnabled(template.getEnabled());
            constraint.setSemester(semester);
            constraint.setCreateBy(currentUser);
            constraint.setCreateTime(DateUtils.getNowDate());
            constraint.setUpdateBy(currentUser);
            constraint.setUpdateTime(DateUtils.getNowDate());
            constraints.add(constraint);
        }

        // 批量插入
        int result = 0;
        for (AcScheduleConstraint constraint : constraints) {
            result += acScheduleConstraintMapper.insertAcScheduleConstraint(constraint);
        }
        
        return result;
    }

    /**
     * 应用默认模板到指定学期
     *
     * @param semester 学期
     * @return 应用结果
     */
    @Override
    @Transactional
    @CacheEvict(value = "acScheduleConstraint", allEntries = true)
    public int applyDefaultTemplate(String semester) {
        // 查询默认模板
        List<AcScheduleConstraintTemplate> defaultTemplates = acScheduleConstraintTemplateMapper.selectDefaultTemplates();
        if (defaultTemplates == null || defaultTemplates.isEmpty()) {
            return 0;
        }

        // 删除该学期的现有约束条件
        acScheduleConstraintMapper.deleteConstraintsBySemester(semester);

        // 根据默认模板创建新的约束条件
        List<AcScheduleConstraint> constraints = new ArrayList<>();
        String currentUser = SecurityUtils.getUsername();
        
        for (AcScheduleConstraintTemplate template : defaultTemplates) {
            AcScheduleConstraint constraint = new AcScheduleConstraint();
            constraint.setName(template.getConstraintName());
            // 需要根据约束类型名称查找对应的约束类型ID
            // 这里暂时设置为1，实际应该根据template.getConstraintType()查找对应的ID
            constraint.setConstraintTypeId(1L);
            constraint.setWeight(template.getDefaultWeight());
            constraint.setEnabled(template.getEnabled());
            constraint.setSemester(semester);
            constraint.setCreateBy(currentUser);
            constraint.setCreateTime(DateUtils.getNowDate());
            constraint.setUpdateBy(currentUser);
            constraint.setUpdateTime(DateUtils.getNowDate());
            constraints.add(constraint);
        }

        // 批量插入
        int result = 0;
        for (AcScheduleConstraint constraint : constraints) {
            result += acScheduleConstraintMapper.insertAcScheduleConstraint(constraint);
        }
        
        return result;
    }
    
    /**
     * 批量保存或更新约束权重（如果ID存在则更新，否则创建新记录）
     * 
     * @param constraints 约束条件列表
     * @return 保存或更新成功的记录数
     */
    @Override
    @Transactional
    @CacheEvict(value = "schedule_constraint", key = "'semester:' + #constraints[0].semester")
    public int saveOrUpdateConstraintWeights(List<AcScheduleConstraint> constraints) {
        if (constraints == null || constraints.isEmpty()) {
            return 0;
        }

        int successCount = 0;
        String semester = constraints.get(0).getSemester();
        String currentUser = SecurityUtils.getUsername();
        
        for (AcScheduleConstraint constraint : constraints) {
            // 验证学期一致性
            if (!semester.equals(constraint.getSemester())) {
                throw new IllegalArgumentException("所有约束条件必须属于同一学期");
            }
            
            // 设置审计字段
            constraint.setUpdateBy(currentUser);
            constraint.setUpdateTime(DateUtils.getNowDate());
            
            int result = 0;
            if (constraint.getId() != null) {
                // ID存在，执行更新操作
                result = acScheduleConstraintMapper.updateConstraintWeight(constraint.getId(), constraint.getWeight());
            } else {
                // ID不存在，查找是否已有相同类型和学期的记录
                AcScheduleConstraint existingConstraint = acScheduleConstraintMapper.selectByTypeAndSemester(
                    constraint.getConstraintTypeId(), constraint.getSemester());
                
                if (existingConstraint != null) {
                    // 存在记录，更新权重
                    constraint.setId(existingConstraint.getId());
                    result = acScheduleConstraintMapper.updateConstraintWeight(constraint.getId(), constraint.getWeight());
                } else {
                    // 不存在记录，创建新记录
                    constraint.setCreateBy(currentUser);
                    constraint.setCreateTime(DateUtils.getNowDate());
                    constraint.setEnabled("1"); // 默认启用
                    result = acScheduleConstraintMapper.insertAcScheduleConstraint(constraint);
                }
            }
            
            if (result > 0) {
                successCount++;
            }
        }
        
        return successCount;
    }
}